package com.base.cn.platform.os.service.course.mould;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.course.mould.CouMouldMaterialDao;
import com.base.cn.platform.os.entity.course.material.CouMaterial;
import com.base.cn.platform.os.entity.course.mould.CouMould;
import com.base.cn.platform.os.entity.course.mould.CouMouldMaterial;
import com.base.cn.platform.os.entity.course.mould.CouMouldMaterialCondition;
import com.base.cn.platform.os.service.course.catalog.CourseCatalogBiz;
import com.base.cn.platform.os.service.course.material.CouMaterialBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 模块与素材关联的Biz
 *
 * @author s.li
 * @create 2018-04-23-18:20
 */
@Service
public class CouMouldMaterialBiz extends BaseBiz<CouMouldMaterial,CouMouldMaterialDao> {

    @Autowired
    private CouMaterialBiz couMaterialBiz;
    @Autowired
    private CouMouldBiz couMouldBiz;
    @Autowired
    private CourseCatalogBiz courseCatalogBiz;
    /**
     * 保存模块与素材的关联数据
     * @param mouldId 模块ID
     * @param materialIds 添加的素材ID串
     */
    @Transactional(rollbackFor = IllegalArgumentException.class )
    public void saveCouMouldMaterial(BigDecimal mouldId,String materialIds){
        materialIds = StringUtils.subHeadTailString(materialIds,",");
        String[] arr = materialIds.split(",");
        List<CouMouldMaterial> addList =new ArrayList<>();
        List<CouMouldMaterial> deleteList =new ArrayList<>();
        //查询模块的关联的素材数据列表
        List<CouMouldMaterial> list = this.findCouMouldMaterialListByMouldIds(mouldId.toString(),false,false);
        if(StringUtils.isNotEmpty(materialIds) &&arr!=null && arr.length> 0){
            if(ObjectUtils.isNotEmpty(list)){//如果之前有添加过素材
                Map<BigDecimal,CouMouldMaterial> couMouldMaterialMaps = list.stream().collect(Collectors.toMap(e->e.getMaterialId(),e->e));
                Arrays.stream(arr).forEach(e->{
                    BigDecimal key = new BigDecimal(e);
                    CouMouldMaterial couMouldMaterial = couMouldMaterialMaps.get(key);
                    if(couMouldMaterial!=null){//如果存在于原来的数据中
                        couMouldMaterialMaps.remove(key);//删除
                    }else{//如果不存在
                        couMouldMaterial = new CouMouldMaterial();
                        couMouldMaterial.setMouldId(mouldId);
                        couMouldMaterial.setMaterialId(new BigDecimal(e));
                        addList.add(couMouldMaterial);//添加到删除列表
                    }
                });
                //如果通过上面的处理，Map中还有数据，则证明这个数据不应该存在，
                //因此要添加到删除列表中，以便后续删除操作
                if(couMouldMaterialMaps.size()>0){
                    couMouldMaterialMaps.forEach((k,v)->{
                        deleteList.add(v);
                    });
                }
            }else{//如果模块没有添加过任何的素材
                Arrays.stream(arr).forEach(e->{
                    CouMouldMaterial couMouldMaterial = new CouMouldMaterial();
                    couMouldMaterial.setMouldId(mouldId);
                    couMouldMaterial.setMaterialId(new BigDecimal(e));
                    addList.add(couMouldMaterial);//添加到删除列表
                });
            }
        }else{
            if(ObjectUtils.isNotEmpty(list)){
                deleteList.addAll(list);
            }
        }
        //添加新的记录
        if(ObjectUtils.isNotEmpty(addList)){
            this.batchSave(addList);
            //同时给对应的课程关联的模块添加目录
            courseCatalogBiz.saveMouldMaterialData(addList);
        }
        //删除不应该存在数据
        if(ObjectUtils.isNotEmpty(deleteList)){
            String _materialIds = deleteList.stream().map(e->e.getMaterialId().toString()).collect(Collectors.joining(","));
            this.deleteWhereSql(" mouldId = "+mouldId +" and materialId in ("+_materialIds+")");
            //同时删除给对应课程的关联的模块目录
            courseCatalogBiz.deleteMouldMaterialData(deleteList);
        }
    }
    /**
     * 查询模块的关联的素材集合
     * @param mouldIds
     * @return
     */
    public Map<BigDecimal,List<CouMouldMaterial>> getMouldToMaterialMap(String mouldIds){
        if(StringUtils.isNotEmpty(mouldIds)){
            List<CouMouldMaterial> list = this.findCouMouldMaterialListByMouldIds(mouldIds,false,true);
            if(ObjectUtils.isNotEmpty(list)){
                return list.stream().collect(Collectors.groupingBy(e->e.getMouldId()));
            }
        }
        return null;
    }

    /**
     * 通过素材ID串，查询CouMouldMaterial数据列表
     * @param materialIds 素材ID串
     * @param setMouldData 是否设置模块数据
     * @param setMaterialData 是否设置素材数据
     * @return List<CouMouldMaterial>
     */
    public List<CouMouldMaterial> findCouMouldMaterialListByMaterialIds(String materialIds,
                                                                        boolean setMouldData,
                                                                        boolean setMaterialData){
        CouMouldMaterialCondition condition = new CouMouldMaterialCondition();
        condition.setMaterialIds(materialIds);
        List<CouMouldMaterial> list = this.findCouMouldMaterialList(condition,setMouldData,setMaterialData);
        return list;
    }

    /**
     * 通过模块ID串，查询CouMouldMaterial数据列表
     * @param mouldIds 模块ID串
     * @param setMouldData 是否设置模块数据
     * @param setMaterialData 是否设置素材数据
     * @return List<CouMouldMaterial>
     */
    public List<CouMouldMaterial> findCouMouldMaterialListByMouldIds(String mouldIds,
                                                                     boolean setMouldData,
                                                                     boolean setMaterialData){
        CouMouldMaterialCondition condition = new CouMouldMaterialCondition();
        condition.setMouldIds(mouldIds);
        List<CouMouldMaterial> list = this.findCouMouldMaterialList(condition,setMouldData,setMaterialData);
        return list;
    }

    /**
     * 多条件查询 CouMouldMaterial数据列表
     * @param condition 查询条件对象
     * @param setMouldData 是否设置模块数据
     * @param setMaterialData 是否设置素材数据
     * @return List<CouMouldMaterial>
     */
    public List<CouMouldMaterial> findCouMouldMaterialList(CouMouldMaterialCondition condition,boolean setMouldData,boolean setMaterialData){
        String whereSql = getWhereSql(condition);
        List<CouMouldMaterial> list = this.find(whereSql,condition.getCount(),null);;
        this.setMouldData(list,setMouldData);
        this.setMaterialData(list,setMaterialData);
        return list;
    }

    //=====================================

    /**
     * 设置素材数据
     * @param couMouldMaterialList
     * @param setMaterialData
     * @return
     */
    private  List<CouMouldMaterial> setMaterialData(List<CouMouldMaterial> couMouldMaterialList ,boolean setMaterialData){
        if(ObjectUtils.isNotEmpty(couMouldMaterialList) && setMaterialData){
            String materialIds = couMouldMaterialList.stream().map(e->e.getMaterialId().toString()).collect(Collectors.joining(","));
            List<CouMaterial> materialList = couMaterialBiz.find(" id in ("+materialIds+")",null,null);
            if(ObjectUtils.isNotEmpty(materialList)){
                Map<BigDecimal,CouMaterial> couMaterialMaps = materialList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
                couMouldMaterialList.forEach(e->{
                    CouMaterial material = couMaterialMaps.get(e.getMaterialId());
                    e.setCouMaterial(material);
                });
            }
        }
        return  couMouldMaterialList;
    }
        /**
         * 设置模块数据
         * @param couMouldMaterialList
         * @param setMouldData
         * @return
         */
    private List<CouMouldMaterial>  setMouldData(List<CouMouldMaterial> couMouldMaterialList ,boolean setMouldData) {
        if(ObjectUtils.isNotEmpty(couMouldMaterialList) && setMouldData){
            String mouldIds = couMouldMaterialList.stream().map(e->e.getMouldId().toString()).collect(Collectors.joining(","));
            List<CouMould> couMouldList = couMouldBiz.findCouMouldByIds(mouldIds,false,false,false);
            if(ObjectUtils.isNotEmpty(couMouldList)){
                Map<BigDecimal,CouMould> couMouldMaps = couMouldList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
                couMouldMaterialList.forEach(e->{
                    CouMould mould = couMouldMaps.get(e.getMouldId());
                    e.setCouMould(mould);
                });
            }
        }
        return couMouldMaterialList;
    }

    private String getWhereSql(CouMouldMaterialCondition condition){
        StringBuilder whereSql = new StringBuilder(" 1=1");
        if(ObjectUtils.isNotEmpty(condition)){
            if(StringUtils.isNotEmpty(condition.getMouldIds())){
                whereSql .append(" and mouldId in (").append(condition.getMouldIds()+")");
            }
            if(StringUtils.isNotEmpty(condition.getMaterialIds())){
                whereSql .append(" and materialId in (").append(condition.getMaterialIds()+")");
            }
        }
        return  whereSql.toString();
    }
}
